<template>
  <a-modal
    :title="record | modalTitle"
    :width="480"
    :maskClosable="false"
    :visible="visible"
    :confirmLoading="confirmLoading"
    @ok="handleSubmit"
    @cancel="handleCancel"
  >
    <a-spin :spinning="confirmLoading">
      <a-form :form="form" v-bind="formItemLayout">
        <a-form-item
          v-show="!record || (record && record[UserPickerOptions.pid] !== UserPickerOptions.root)"
          label="上级部门"
        >
          <a-tree-select
            style="width: 100%"
            :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
            :treeData="treeData"
            treeDefaultExpandAll
            dropdownMatchSelectWidth
            v-decorator="[
              'parentId',
              {
                rules: [{ required: true, message: '请选择上级部门！' }]
              }
            ]"
          >
            <span slot="title" slot-scope="p" :title="p.name">
              {{ p.name }}
            </span>
          </a-tree-select>
        </a-form-item>
        <a-form-item label="部门名称">
          <!-- { validator: validator.nameValidator } -->
          <s-input
            v-decorator="[
              'name',
              { rules: [{ required: true, message: '请输入部门名称！', transform: value => value && value.trim() }] }
            ]"
            :limit="128"
            :spell-check="false"
            autocomplete="off"
          />
        </a-form-item>
      </a-form>
    </a-spin>
  </a-modal>
</template>

<script>
import { SInput } from '@/components';
import { updateOrg, createOrg } from '@/api/authenticationCenter/structure';
import { validateField } from '@/api/common';
import { asyncValidateMixin } from '@/utils/mixin';
import { setArrayToTree, getParentNode } from '@/utils/util';
import { UserPickerOptions } from '@/components/UserPicker/options';
import cloneDeep from 'lodash.clonedeep';

export default {
  name: 'OrgForm',
  components: {
    SInput
  },
  mixins: [asyncValidateMixin],
  data() {
    return {
      formItemLayout: {
        labelCol: {
          xs: { span: 24 },
          sm: { span: 6 }
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 18 }
        }
      },
      record: null,
      visible: false,
      confirmLoading: false,
      form: this.$form.createForm(this),
      UserPickerOptions
    };
  },
  props: {
    partyList: {
      type: Array,
      default: []
    }
  },
  filters: {
    modalTitle(value) {
      return `${value ? '编辑' : '新建'}部门`;
    }
  },
  computed: {
    treeData() {
      let partyListFiltered = [];
      const partyList = cloneDeep(this.partyList);
      partyList.forEach(party => {
        party.scopedSlots = { title: 'title' };
        party.value = party.id;
        // 编辑模式下，上级部门不能为自己及自己，禁用自己
        if (this.record && party.id === this.record.id) {
          party.disabled = true;
        }
      });

      if (this.record) {
        // 隐藏子部门，服务端数据已排序，截取即可
        const startIndex = partyList.findIndex(item => item.id === this.record.id);
        let endIndex = partyList.findIndex(
          (item, index) => index >= startIndex && item.id !== this.record.id && item.parentId === this.record.parentId
        );
        // 寻找和父节点同一节点的第一个元素
        if (endIndex === -1) {
          const parentNode = partyList.find(item => item.id === this.record.parentId);
          if (parentNode) {
            endIndex = partyList.findIndex(
              (item, index) => index >= startIndex && item.id !== parentNode.id && item.parentId === parentNode.parentId
            );
            if (endIndex === -1) {
              endIndex = startIndex;
            }
          }
        }
        partyListFiltered = partyList.filter(
          (item, index) => index <= startIndex || (index >= endIndex && endIndex !== -1)
        );
      } else {
        partyListFiltered = partyList;
      }

      // 组织机构部门树状结构
      const tree = setArrayToTree({
        ...UserPickerOptions,
        data: partyListFiltered,
        collection: 'children'
      });

      return tree;
    }
  },
  created() {
    // this.$_asyncValidateMixin_init([
    //   {
    //     fieldName: 'name',
    //     caller: validateField,
    //     extraParams: this.getExtraParams
    //   }
    // ]);
  },
  methods: {
    add(record) {
      this.visible = true;
      this.$nextTick(() => {
        this.form.setFieldsValue({ parentId: record.id });
      });
    },
    edit(record) {
      this.visible = true;
      const {
        form: { setFieldsValue }
      } = this;
      const { name } = record;
      this.record = record;
      this.$nextTick(() => {
        setFieldsValue({
          name,
          parentId: record.parentId
        });
      });
    },
    handleSubmit() {
      const {
        form: { validateFields, getFieldsValue }
      } = this;
      this.confirmLoading = true;
      // 远程校验通过的字段不参与最终校验
      // 最终校验通过后，values 不包含未参与最终校验的远程字段，需要主动获取所有字段值
      const req = getFieldsValue();
      // const fieldNames = this.$_asyncValidateMixin_fieldsFilter();
      // validateFields(fieldNames, async (errors, values) => {
      validateFields(async (errors, values) => {
        if (!errors) {
          for (let key in req) {
            if (key === 'name') {
              req[key] = req[key].trim();
            }
          }

          if (this.record) {
            req.id = this.record.id;
          }
          try {
            const res = this.record ? await updateOrg(req) : await createOrg(req);
            this.confirmLoading = false;
            if (res.code === 'sso.ok') {
              // 新建部门需要传入所有父节点id
              const parentIds = req.id ? [] : getParentNode(this.partyList, req.parentId).map(item => item.id);
              this.$emit('ok', parentIds);
              this.handleCancel();
              this.$message.success(res.message);
            }
          } catch (error) {
            this.confirmLoading = false;
          }
        } else {
          this.confirmLoading = false;
        }
      });
    },
    handleCancel() {
      if (this.confirmLoading) return;
      this.visible = false;
      this.record = null;
      const {
        form: { resetFields }
      } = this;
      // 重置远程校验 needVerify
      this.$_asyncValidateMixin_resetFields();
      resetFields();
    },
    // 表单校验额外参数
    getExtraParams() {
      return {
        moduleName: 'ScriptGroup',
        type: this.record ? 'update' : 'create',
        ...(this.record ? { id: this.record.id } : {})
      };
    }
  }
};
</script>
